package cn.skyisazure.metacompare.sqlcompare.mysql;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.skyisazure.metacompare.metaVo.EntityDataSourceInfoVO;
import cn.skyisazure.metacompare.metaVo.EntityTableInfoVO;
import cn.skyisazure.metacompare.metaVo.MetaColumnRespVO;
import cn.skyisazure.metacompare.metaVo.MetaIndexRespVO;
import cn.skyisazure.metacompare.sqlcompare.enums.CompareScopeStrategy;
import cn.skyisazure.metacompare.sqlcompare.meta.ColumnCM;
import cn.skyisazure.metacompare.sqlcompare.meta.DataSourceCM;
import cn.skyisazure.metacompare.sqlcompare.meta.IndexCM;
import cn.skyisazure.metacompare.sqlcompare.meta.TableCM;
import cn.skyisazure.metacompare.sqlcompare.utils.DBTypeConvert;
import cn.skyisazure.metacompare.sqlcompare.utils.MysqlDBTypeConvert;
import lombok.Data;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 业务元数据(BusinessMate)转为对比元数据(CompareMate)的工具类
 *
 * @author wangjj
 * @date 2025/3/19 下午5:36
 */
@Data
public class MysqlMetaConvert {

    /* 元数据 */
    private final EntityDataSourceInfoVO sourceEntityDataSourceInfoVO;
    private final EntityDataSourceInfoVO targetEntityDataSourceInfoVO;
    // 对比策略(库 - 表)
    private final CompareScopeStrategy compareScopeStrategy;
    /* 元数据列类型转换（列类型） */
    public final DBTypeConvert dbTypeConvert = MysqlDBTypeConvert.INSTANCE;

    public MysqlMetaConvert(EntityDataSourceInfoVO sourceEntityDataSourceInfoVO,
                            EntityDataSourceInfoVO targetEntityDataSourceInfoVO,
                            CompareScopeStrategy compareScopeStrategy) {
        this.compareScopeStrategy = compareScopeStrategy;
        // 复制数据，防止对原始数据的修改，可以自定义复制逻辑
        this.sourceEntityDataSourceInfoVO = ObjectUtil.clone(sourceEntityDataSourceInfoVO);
        this.targetEntityDataSourceInfoVO = ObjectUtil.clone(targetEntityDataSourceInfoVO);
    }

    public DataSourceCM getSchemaDataSource(String type) {

        EntityDataSourceInfoVO currentEntityDataSourceInfoVO = type.equals("source") ? sourceEntityDataSourceInfoVO : targetEntityDataSourceInfoVO;

        DataSourceCM dataSourceCM = new DataSourceCM();
        dataSourceCM.setId(currentEntityDataSourceInfoVO.getQueryKey())
                .setName(currentEntityDataSourceInfoVO.getDatabaseName())
                .setExistFlag(ObjUtil.isNotEmpty(currentEntityDataSourceInfoVO.getId()))
                .setBase(currentEntityDataSourceInfoVO.getBase());
        return dataSourceCM;
    }

    /**
     * 查询库中所有表的表名
     */
    public List<TableCM> getSchemaTables(String type) {

        EntityDataSourceInfoVO currentEntityDataSourceInfoVO = type.equals("source") ? sourceEntityDataSourceInfoVO : targetEntityDataSourceInfoVO;

        if (compareScopeStrategy.equals(CompareScopeStrategy.DATASOURCE) && ObjUtil.isEmpty(currentEntityDataSourceInfoVO.getId())){
            return Collections.emptyList();
        }
        List<EntityTableInfoVO> entityTableInfos = currentEntityDataSourceInfoVO.getEntityTableInfos().stream()
                .sorted(Comparator.comparing(x -> x.getMetaTable().getSort(),Comparator.reverseOrder())).collect(Collectors.toList());
        // List<EntityTableInfoVO> entityTableInfos = entityDataSourceInfoVO.getEntityTableInfos();
        List<TableCM> tables = new ArrayList<>();
        for (EntityTableInfoVO tableInfoVO : entityTableInfos) {
            TableCM table = TableCM.build(tableInfoVO,
                    dbTypeConvert,
                    currentEntityDataSourceInfoVO);
            tables.add(table);
        }
        return tables;
    }

    /**
     * 获取库中所有列
     */
    public List<ColumnCM> getSchemaColumns(String type) {

        EntityDataSourceInfoVO currentEntityDataSourceInfoVO = type.equals("source") ? sourceEntityDataSourceInfoVO : targetEntityDataSourceInfoVO;

        if (compareScopeStrategy.equals(CompareScopeStrategy.DATASOURCE) && ObjUtil.isEmpty(currentEntityDataSourceInfoVO.getId())){
            return Collections.emptyList();
        }
        // 增加排序
        List<EntityTableInfoVO> entityTableInfos = currentEntityDataSourceInfoVO.getEntityTableInfos().stream()
                .sorted(Comparator.comparing(x -> x.getMetaTable().getSort())).collect(Collectors.toList());
        // List<EntityTableInfoVO> entityTableInfos = entityDataSourceInfoVO.getEntityTableInfos().stream()
        //         .sorted(Comparator.comparing(x -> x.getMetaTable().getCode())).collect(Collectors.toList());
        List<ColumnCM> columns = new ArrayList<>();
        for (EntityTableInfoVO entityTableInfo : entityTableInfos) {
            // 增加排序
            List<MetaColumnRespVO> fields = entityTableInfo.getFields().stream()
                    // .filter(col-> !ArrayUtil.contains(new MysqlColumnType[]{MysqlColumnType.RELATION, MysqlColumnType.FORMULA},col.getType()))
                    .sorted(Comparator.comparingInt(MetaColumnRespVO::getSort)).collect(Collectors.toList());
            for (MetaColumnRespVO field : fields) {
                /* 金额元转分 * 100
                if (field.getType().equals(MysqlColumnType.MONEY) && StrUtil.isNotBlank(field.getDefaultValue())){// 金额存储分单位，前端传入为元，元转分。
                    field.setDefaultValue(new BigDecimal(field.getDefaultValue()).multiply(new BigDecimal("100")).toBigInteger().toString());
                }*/
                ColumnCM column = ColumnCM.build(field,
                        dbTypeConvert,
                        entityTableInfo);
                columns.add(column);
            }
        }
        return columns;
    }

    /**
     * 查询表的索引
     *
     */
    public List<IndexCM> getSchemaIndices(String type) {

        EntityDataSourceInfoVO currentEntityDataSourceInfoVO = type.equals("source") ? sourceEntityDataSourceInfoVO : targetEntityDataSourceInfoVO;

        if (compareScopeStrategy.equals(CompareScopeStrategy.DATASOURCE) &&
                ObjUtil.isEmpty(currentEntityDataSourceInfoVO.getId())){
            return Collections.emptyList();
        }
        // 增加排序
        List<EntityTableInfoVO> entityTableInfos = currentEntityDataSourceInfoVO.getEntityTableInfos().stream()
                .sorted(Comparator.comparing(x -> x.getMetaTable().getSort())).collect(Collectors.toList());
        // List<EntityTableInfoVO> entityTableInfos = entityDataSourceInfoVO.getEntityTableInfos().stream()
        //         .sorted(Comparator.comparing(x -> x.getMetaTable().getCode())).collect(Collectors.toList());
        List<IndexCM> indices = new ArrayList<>();
        for (EntityTableInfoVO entityTableInfo : entityTableInfos) {
            // 增加排序
            List<MetaIndexRespVO> indeies = entityTableInfo.getIndexes().stream()
                    .sorted(Comparator.comparing(MetaIndexRespVO::getCode)).collect(Collectors.toList());
            for (MetaIndexRespVO indexVo : indeies) {
                IndexCM index = new IndexCM();
                index.setId(indexVo.getQueryKey());
                index.setTableName(entityTableInfo.getMetaTable().getCode());
                index.setTableId(entityTableInfo.getMetaTable().getQueryKey());
                index.setIndexName(indexVo.getCode());
                index.setUniqueFlag(indexVo.getUniqueFlag());
                index.setIndexType("BTREE");
                index.setIndexComment("");// 索引的备注，暂时没有涉及
                index.setColumnNames(Arrays.stream(indexVo.getColumnNames().split(","))
                        .sorted(String::compareTo).collect(Collectors.joining(",")));
                indices.add(index);
            }
        }

        return indices;
    }




    public boolean existTableId(String tableId){
        List<EntityTableInfoVO> tableInfos = this.sourceEntityDataSourceInfoVO.getEntityTableInfos();
        if (CollectionUtil.isEmpty(tableInfos)) {
            return false;
        }
        return tableInfos.stream()
                .anyMatch(tableInfoVO -> tableInfoVO.getMetaTable().getQueryKey().equals(tableId));
    }

}
